﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using myNico.view;
using System.Windows.Threading;
using nicotool;
using myNico.Mode;
using System.Threading;
using System.ComponentModel;
using System.Collections.ObjectModel;
using myNico.Dao;
using System.IO;
using System.Net;

namespace myNico
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window  
    {
        #region 字段
        /// <summary>
        /// 计时器
        /// </summary>
        DispatcherTimer dt  = new DispatcherTimer();
        /// <summary>
        /// 多线程同步的字段
        /// </summary>
        static object syncObject = new object();
        /// <summary>
        /// 统计速度的间隔
        /// </summary>
        int interval = 1000;

        /// <summary>
        /// 批量下载计时器，实现同时下载数限制
        /// </summary>
        DispatcherTimer list_dt = new DispatcherTimer();
        /// <summary>
        /// 
        /// <summary>
        /// 批量下载标示
        /// </summary>
        private bool xiazi_flag = false;
        #endregion

        #region 属性
        /// <summary>
        /// 下载文件列表
        /// </summary>
        public ObservableCollection<DownloadItemViewModel> DownloadFileList { get; private set; }
       
        #endregion

        private BackgroundWorker backgroudWorker;
        public MainWindow()
        {
            InitializeComponent();
            this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            
            txtSm.Text = "sm19087508";
            chush();
            dt.Interval = TimeSpan.FromMilliseconds(interval);
            dt.Tick += new EventHandler(dt_Tick);
            dt.Start();

            list_dt.Interval = TimeSpan.FromMilliseconds(interval);//设置计时器时间
            list_dt.Tick += new EventHandler(dt_list); //下载数限制用计时器方法
        }

        /// <summary>
        /// 重写关闭
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosing(CancelEventArgs e)
        {
            if (MessageBox.Show("是否关闭", "", MessageBoxButton.OKCancel, MessageBoxImage.None) == MessageBoxResult.OK)
            {
                if (!string.IsNullOrEmpty(txt_UserName.Text) && !string.IsNullOrEmpty(txt_PassWord.Password))
                {
                    Mode.config config = new Mode.config();
                    config.UserName = txt_UserName.Text;
                    config.PassWord = txt_PassWord.Password;
                    config.ProxyIp = app_data.ProxyIp;
                    config.ProxyPort = app_data.ProxyPort;
                    Dao.Dao_config.SaveAsXmlFormat(config, "config.xml");

                    List<ViewModels> list_viewModels = new List<ViewModels>(); 
                    foreach (var item in DownloadFileList)
                    {
                        ViewModels vm = new ViewModels();
                        vm.Description = item.Description;
                        vm.FileName = item.FileName;
                        vm.smName = item.smName;
                        vm.ThumbnailUrl = item.ThumbnailUrl;
                        vm.title = item.title;
                        vm.movieType = item.movieType;
                        if (item.xiazflag == 2)
                        {
                            vm.xiazflag = item.xiazflag;
                        }
                        else
                        {
                            vm.xiazflag = 0;
                        }
                        list_viewModels.Add(vm);

                    }
                    Dao.Dao_ViewModels.SaveAsXmlFormat(list_viewModels, "downlist.xml");
                 
                }
                base.OnClosing(e);
            }
            else
            {
                e.Cancel=true;
            }
        }
        private void chush()
        {
            
            backgroudWorker = new BackgroundWorker(); //后台线程
            backgroudWorker.WorkerSupportsCancellation = true; //支持异步取消
            txt_UserName.Focus(); //聚焦用户名
            backgroudWorker.DoWork += new DoWorkEventHandler(backgroudWorker_DoWork); //添加操作事件
            backgroudWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroudWorker_RunWorkerCompleted);
            backgroudWorker.RunWorkerCompleted+=new RunWorkerCompletedEventHandler(backgroudWorker_RunWorkerCompleted);
            backgroudWorker.ProgressChanged += new ProgressChangedEventHandler(backgroudWorker_ProgressChanged);
            DownloadFileList = new ObservableCollection<DownloadItemViewModel>();
            dg_list.ItemsSource = DownloadFileList;
            setEnabled(false);
            if (File.Exists("downlist.xml"))
            {
                List<ViewModels> vms = Dao_ViewModels.LoadFromXml("downlist.xml");
                foreach (var item in vms)
                {
                    DownloadItemViewModel vm = new DownloadItemViewModel();
                    vm.Description = item.Description;
                    vm.FileName = item.FileName;
                    vm.smName = item.smName;
                    vm.ThumbnailUrl = item.ThumbnailUrl;
                    vm.title = item.title;
                    vm.movieType = item.movieType;
                    vm.xiazflag = item.xiazflag;
                   
                    DownloadFileList.Add(vm);

                }
            }
            if (File.Exists("config.xml"))
            {
                config cf = Dao_config.LoadFromXml("config.xml");
                txt_PassWord.Password = cf.PassWord;
                txt_UserName.Text = cf.UserName;
                if (cf.ProxyIp != null && cf.ProxyPort != null)
                {
                    
                     
                    app_data.proxy = new WebProxy(cf.ProxyIp,  (int)cf.ProxyPort);
                    app_data.ProxyIp = cf.ProxyIp;
                    app_data.ProxyPort = cf.ProxyPort;
                    nicotool.nico_data.proxy = app_data.proxy;
                }
            }
           
        }
        
        private void LoginsetEnabled(bool flag)
        {
            txt_PassWord.IsEnabled = flag;
            txt_UserName.IsEnabled = flag;

            btn_login.IsEnabled = flag;
           
        }
        private void setEnabled(bool flag)
        {
            txtSm.IsEnabled = flag;
            dg_list.IsEnabled = flag;
            btn_add.IsEnabled = flag;
            btn_Pause.IsEnabled = flag;
            btn_start.IsEnabled = flag;
        }

        #region 登陆线程

        void backgroudWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

        }

        void backgroudWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                MessageBox.Show("cance");
                return;
            }
            //this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
            //{
            //    setEnabled(false);
              
            //});
        }

        void backgroudWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (backgroudWorker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }
            Dictionary<string, string> dc = (Dictionary<string, string>)e.Argument;



            string username, password;
            username = dc["username"];
            password = dc["password"];
            
            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            {
                MessageBox.Show("帐号或者密码不能为空", "登陆错误", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            app_data.UserName = username;
            app_data.PassWord = password;
            app_data.sysPath = AppDomain.CurrentDomain.BaseDirectory;
            //   btn_login.Content = "登陆成功";
            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
            {
                btn_login.Content = "登陆中";
                LoginsetEnabled(false);
                setEnabled(false);
            });
            try
            {
                if (nicotool.nicovideo.LoginToNicovideo(app_data.UserName, app_data.PassWord))
                {

                    //MessageBox.Show("ok");
                    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
                    {
                        btn_login.Content = "登陆成功";
                        LoginsetEnabled(false);
                        setEnabled(true);
                        MessageBox.Show("登陆成功");
                    });

                }
                else
                {
                    MessageBox.Show("帐号错误");
                    // btn_login.Content = "登陆";
                    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
                    {
                        LoginsetEnabled(true);
                        setEnabled(false);
                    });
                }
            }
            catch (Exception ex)
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
                {
                    LoginsetEnabled(true);
                    setEnabled(false);
                });
                MessageBox.Show("登陆错误",ex.Message);
            }
           
        }
        #endregion


        void dt_Tick(object sender, EventArgs e)
        {
            //dt.Stop();
            //W_login w_login = new W_login();
            //w_login.Owner = this;
            //if (w_login.ShowDialog() == true)
            //{



            //}

            double speed = 0;
            DownloadFileList.AsParallel().ForAll(t =>
            {
                t.InitSpeed(interval);
                speed += t.Speed;
            });
           

        }

        private void btn_info_Click(object sender, RoutedEventArgs e)
        {
            if (txtSm.Text == "") return;

            string strSm = txtSm.Text.Replace(@"http://http://www.nicovideo.jp/watch/", "").Trim();
            strSm = strSm.Split('?')[0];
            try
            {
                FlvInfo flvinfo = getInfo(strSm);
                if (flvinfo == null)
                {
                    MessageBox.Show("视频信息获取失败");
                    return;
                }
                var thumbinfo = ThumbInfo.Create(strSm);
             flvinfo.GetComments_xml(thumbinfo.CommentNum).Save(app_data.sysPath+flvinfo.Id+"弹幕.xml");
             var client = nicovideo.GetWebClientForFlv(strSm);
             client.DownloadFile(flvinfo.FlvUrl, strSm + "."+thumbinfo.movieType);

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
          
        }

        private FlvInfo getInfo(string strSm)
        {
            try
            {
                var flvinfo = FlvInfo.Create(strSm);
                StringBuilder sb = new StringBuilder();
                sb.Append("FlvInfo信息 \r\n");
                sb.Append("动画id：" + flvinfo.Id + "\r\n");
                sb.Append("动画网址：" + flvinfo.FlvUrl + "\r\n");
                sb.Append("违反信息网址：" + flvinfo.AbuseLink + "\r\n");
                sb.Append("服务器网址：" + flvinfo.MessageServer + "\r\n");
                sb.Append("线程id：" + flvinfo.ThreadId + "\r\n");
                systool.fileWrite(sb.ToString(), app_data.sysPath + flvinfo.Id + "信息.txt");
                return flvinfo;
            }
            catch (Exception ex)
            {
                tool.wf_log(ex.Message.ToString());
                return null;
            }
           

        }

        private void btn_login_Click(object sender, RoutedEventArgs e)
        {
            tool.SetCertificatePolicy();
            Dictionary<string, string> dc = new Dictionary<string, string>();
            dc.Add("username", txt_UserName.Text);
            dc.Add("password", txt_PassWord.Password);
            
            backgroudWorker.RunWorkerAsync(dc); //开始后台线程
        }

        //private void checkLogin()
        //{
        //    string username, password;
        //    username = txt_UserName.Text;
        //    password = txt_PassWord.Password;
        //    if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
        //    {
        //        MessageBox.Show("帐号或者密码不能为空", "登陆错误", MessageBoxButton.OK, MessageBoxImage.Warning);
        //        return;
        //    }
        //    app_data.UserName = username;
        //    app_data.PassWord = password;
        //    app_data.sysPath = AppDomain.CurrentDomain.BaseDirectory;
        //    btn_login.Content = "登陆成功";
        //    setEnabled(false);
        //    if (nicotool.nicovideo.LoginToNicovideo(app_data.UserName, app_data.PassWord))
        //    {

        //        //MessageBox.Show("ok");
        //        setEnabled(false);
        //    }
        //    else
        //    {
        //        MessageBox.Show("帐号错误");
        //        btn_login.Content = "登陆";
        //        setEnabled(true);
        //    }
        //}
        



        #region 按钮
        private void btn_add_Click(object sender, RoutedEventArgs e)
        {
         //   string downloadUrl = txtSm.Text;
            string downloadUrl = txtSm.Text.Replace("http://www.nicovideo.jp/watch/", "").Trim();
            downloadUrl = downloadUrl.Split('?')[0];
            if (DownloadFileList.Where(x => x.smName == downloadUrl).Count() > 0)
            {
                MessageBox.Show("文件已存在下载队列中");
                return;
            }
            if (!string.IsNullOrEmpty(downloadUrl))
            {
                
                Thread thread = new Thread(new ParameterizedThreadStart(addUrl));
                thread.Start(downloadUrl);
                btn_add.IsEnabled = false;
                btn_add.Content = "获取中";
              
               
               
            }
        }

        private void btn_Pause_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (DownloadFileList.Count > 0)
                {
                    //DownloadFileList.AsParallel().ForAll(t =>
                    //{
                    //    t.PauseDownload();
                    //});
                    DownloadFileList.AsParallel().ForAll(t =>
                    {
                        if (t.xiazflag==1)
                        {
                            t.PauseDownload();
                        }
                    });
                    list_dt.Stop();
                }
            }
            catch (Exception ex)
            {
                tool.wf_log(ex.Message.ToString());
                MessageBox.Show(ex.Message);
            }
            

        }

        
        /// <summary>
        /// 全部下载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_start_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (DownloadFileList.Count > 0)//如果下载列表有数据
                {
                    //DownloadFileList.Where(x=>x.xiazflag<1).AsParallel().ForAll(t => 
                    //{
                    //    Thread thread = new Thread(new ParameterizedThreadStart(startall));
                    //    thread.Start(t);
                    //   // t.StartDownload(); //启动下载
                    //});

                    try
                    {
                        btn_start.IsEnabled = false;

                        list_dt.Start();
                    }
                    catch (Exception ex)
                    {
                        xiazi_flag = false;
                        btn_start.IsEnabled = true;
                        tool.wf_log(ex.Message.ToString());
                        MessageBox.Show(ex.Message);
                    }

                }
            }
            catch (Exception ex)
            {
                tool.wf_log(ex.Message.ToString());
                MessageBox.Show(ex.Message);
            }
            
        }

        /// <summary>
        /// 网格行中开始按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dg_btn_start(object sender, RoutedEventArgs e)
        {
            try
            {
                DownloadItemViewModel divm = dg_list.SelectedItem as DownloadItemViewModel;
                if (divm.xiazflag != 1 && divm.xiazflag != 2)
                {
                    divm.StartDownload();
                }
            }
            catch (Exception ex)
            {
                tool.wf_log(ex.Message.ToString());
                MessageBox.Show(ex.Message);
            }
           
        }
        /// <summary>
        ///  网格行中暂停按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dg_btn_pause(object sender, RoutedEventArgs e)
        {
            DownloadItemViewModel divm = dg_list.SelectedItem as DownloadItemViewModel;
            if (divm.xiazflag == 1)
            {
                divm.PauseDownload();
            }
            
        }
        /// <summary>
        ///  网格行中删除按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dg_btn_del(object sender, RoutedEventArgs e)
        {
            DownloadItemViewModel divm = dg_list.SelectedItem as DownloadItemViewModel;
            divm.PauseDownload();
            DownloadFileList.Remove(divm);
        }

        /// <summary>
        /// 设置菜单按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mi_shez(object sender, RoutedEventArgs e)
        {
            w_config win = new w_config();
            win.Owner = this;
            if (win.ShowDialog() == true)
            {
                if (!string.IsNullOrEmpty(win.txt_ip.Text) && !string.IsNullOrEmpty(win.txt_Port.Text))
                {
                    app_data.ProxyIp = win.txt_ip.Text;
                    try
                    {
                        app_data.ProxyPort = int.Parse(win.txt_Port.Text);
                    }
                    catch (Exception)
                    {

                        app_data.ProxyPort = 21;
                    }

                }
            }
            else
            {
                app_data.ProxyIp = null;
                app_data.ProxyPort = null;
            }
           
            
             
        }
        #endregion

        private void startall()
        {
           List<DownloadItemViewModel> list=(from c in  DownloadFileList where c.xiazflag<1 select c).ToList<DownloadItemViewModel>();
           foreach (var item in list)
           {
               item.StartDownload();
           }
	{
		 
	}
        }

        private void addUrl(object p)
        {
            try
            {
                var file = new DownloadItemViewModel(p.ToString());
                
                   
                
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
                {
                    DownloadFileList.Add(file);
                    btn_add.IsEnabled = true;
                    btn_add.Content = "添加";
                    savelist();
                });



            }
            catch (Exception ex)
            {
                tool.wf_log(ex.Message.ToString());
                MessageBox.Show(ex.Message);
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
                {
                    
                    btn_add.IsEnabled = true;
                    btn_add.Content = "添加";
                });
            }
        }


        private void savelist()
        {
            List<ViewModels> list_viewModels = new List<ViewModels>();
            foreach (var item in DownloadFileList)
            {
                ViewModels vm = new ViewModels();
                vm.Description = item.Description;
                vm.FileName = item.FileName;
                vm.smName = item.smName;
                vm.ThumbnailUrl = item.ThumbnailUrl;
                vm.title = item.title;
                vm.movieType = item.movieType;
                if (item.xiazflag == 2)
                {
                    vm.xiazflag = item.xiazflag;
                }
                else
                {
                    vm.xiazflag = 0;
                }
                list_viewModels.Add(vm);

            }
            Dao.Dao_ViewModels.SaveAsXmlFormat(list_viewModels, "downlist.xml");
        }

        /// <summary>
        /// 清空高清已完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_clear_hight_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (DownloadFileList.Count > 0)//如果下载列表有数据
                {

                    foreach (var item in DownloadFileList.Where(c => c.xiazflag == 2 && c.smType == "高画质").ToList<DownloadItemViewModel>())
                    {
                        DownloadFileList.Remove(item);
                    }
                    savelist();
                }
            }
            catch (Exception ex)
            {
                tool.wf_log(ex.Message.ToString());
                MessageBox.Show(ex.Message);
            }
        }

        private void dg_btn_RE_start(object sender, RoutedEventArgs e)
        {
            try
            {
                DownloadItemViewModel divm = dg_list.SelectedItem as DownloadItemViewModel;
                divm.xiazflag = 0;
                if (divm.xiazflag != 1 && divm.xiazflag != 2)
                {
                    Button but = (Button)e.OriginalSource;
                    but.IsEnabled = false;
                    Thread thread = new Thread(ol =>
                    {
                        divm.StartDownload();
                        this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
                        {
                            ((Button)ol).IsEnabled = true;
                        });
                    });
                    thread.Start(but);

                }
            }
            catch (Exception ex)
            {
                tool.wf_log(ex.Message.ToString());
                MessageBox.Show(ex.Message);
            }
        }


        /// <summary>
        /// 计时器用下载数限制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void dt_list(object sender, EventArgs e)
        {
            if (true == cb_zidsc.IsChecked)
            {
                btn_clear_hight_Click(null, null);

            }
            if (xiazi_flag)
            {
                return;
            }
             
               
           


            int i = (from c in DownloadFileList where c.xiazflag == 1 select c).Count();

            List<DownloadItemViewModel> list = (from c in DownloadFileList where c.xiazflag == 0 select c).ToList<DownloadItemViewModel>();
            if (i > 3 || list.Count <= 0)
            {
                return;
            }

            Thread thread = new Thread(ol =>
            {
                try
                {
                    if (i <= 3)
                    {
                        if (list.Count > 0)
                        {
                          
                            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
                            {
                                ((Button)ol).IsEnabled = true;

                            });
                           
                            list[0].StartDownload();
                            xiazi_flag = false;
                        }
                    }

                }
                catch (Exception ex)
                {
                    tool.wf_log(ex.Message.ToString());
                    MessageBox.Show(ex.Message);
                    list[0].xiazflag = -1;
                    xiazi_flag = false;
                }
            });
            thread.Start(btn_start);
            xiazi_flag = true;

        }
        private void btn_new_Click(object sender, RoutedEventArgs e)
        {
            w_new win = new w_new();
            win.ShowDialog();
        }
        
       

    }
}
